#include "vxdockselector.h"
#include "vxmousetransmitter.h"

VxDockSelector::VxDockSelector(QWidget * parent, Qt::DockWidgetArea orintation, VxDockContainer * container) :
		QWidget(parent), _orientation(orintation), _container(container)
{

	QPushButton * button = new QPushButton(this);

	button->setObjectName("vxDockSelector");
	button->setProperty("orintation", _orientation);

	switch(_orientation){

	case Qt::TopDockWidgetArea:
	case Qt::BottomDockWidgetArea:
		setFixedHeight(HEIGHT);
		setFixedWidth(WIDTH);
		break;

	case Qt::LeftDockWidgetArea:
	case Qt::RightDockWidgetArea:
		setFixedHeight(WIDTH);
		setFixedWidth(HEIGHT);
	default:;
	}

	parent->installEventFilter(this);

	connect(VxMouseTransmitter::instance(), SIGNAL(mouseReleasedIdle(QPoint)),
									this, SLOT(_mouseReleasedIdle(QPoint)));

	connect(VxMouseTransmitter::instance(), SIGNAL(mouseReleasedMove(QPoint)),
									this, SLOT(_mouseReleasedMove(QPoint)));

	setVisible(false);

	button->setGeometry(0,0, this->width(), this->height());

	_showAnimation = new QPropertyAnimation(this, "pos");
	_showAnimation->setDuration(100);

	connect(button, SIGNAL(clicked()), this, SLOT(_showDockContainer()));

}


bool VxDockSelector::eventFilter(QObject *object, QEvent *event)
{
	if (event->type() == QEvent::Resize){
		_activeBorder = _getActiveBorder();
		_hideButton(false);
	}
	return false;
}


void VxDockSelector::_adjustPosition(QPoint * pointFrom, QPoint * pointTo, QPoint * mousep)
{

	_activeBorder = _getActiveBorder();

	QRect wr = parentWidget()->geometry();
	int mx = 0;
	int my = 0;
	int fx = 0;
	int fy = 0;
	if (mousep == NULL){
		mx = fx = (wr.width() - this->width())/2;
		my = fy = (wr.height() - this->height())/2;
	} else {
		mx = mousep->x() - this->width()/2;
		my = mousep->y() - this->height()/2;

		if (mx < 1){
			mx = 1;
		} else
		if (mx > wr.width() - this->width() - 1){
			mx = wr.width() - this->width() - 1;
		}

		if (my < 1){
			my = 1;
		} else
		if (my > wr.height() - this->height() - 1){
			my = wr.height() - this->height() - 1;
		}

		fx = mx;
		fy = my;
	}

	switch(_orientation){
	case Qt::TopDockWidgetArea:
		my = 0;
		fy = my - HEIGHT;
		break;

	case Qt::BottomDockWidgetArea:
		my = wr.height() - this->height();
		fy = my + HEIGHT;
		break;

	case Qt::LeftDockWidgetArea:
		mx = 0;
		fx = mx - HEIGHT;
		break;

	case Qt::RightDockWidgetArea:
		mx = wr.width() - this->width();
		fx = mx + HEIGHT;
		break;

	default:;
	}

	pointFrom->setX(fx);
	pointFrom->setY(fy);

	pointTo->setX(mx);
	pointTo->setY(my);

}

void VxDockSelector::_showButton(QPoint mousep, bool anim)
{
	QPoint pointFrom;
	QPoint pointTo;

	_adjustPosition(&pointFrom, &pointTo, &mousep);

	setVisible(true);

	if (!anim){
		this->move(pointTo);
		return;
	}

	_showAnimation->setDirection(QAbstractAnimation::Forward);

	_showAnimation->setStartValue(pointFrom);
	_showAnimation->setEndValue(pointTo);


	disconnect(_showAnimation, SIGNAL(finished()), this, SLOT(hide()));
	_showAnimation->start();

}


void VxDockSelector::_hideButton(bool anim)
{

	if (!anim){
		setHidden(true);
		return;
	}

	_showAnimation->setDirection(QAbstractAnimation::Backward);

	connect(_showAnimation, SIGNAL(finished()), this, SLOT(hide()));
	_showAnimation->start();

}


QRect VxDockSelector::_getActiveBorder()
{
	QRect r(0,0, parentWidget()->width(), parentWidget()->height());

	r.setLeft(r.left() + HEIGHT);
	r.setRight(r.right() - HEIGHT);
	r.setTop(r.top() + HEIGHT);
	r.setBottom(r.bottom() - HEIGHT);

	return r;
}


Qt::DockWidgetArea VxDockSelector::_inActive(QPoint point)
{
	if (point.y() < 0 || point.x() < 0 ||
		point.x() >= parentWidget()->width() ||
		point.y() >= parentWidget()->height()){
		return Qt::NoDockWidgetArea;
	}

	if (point.y() < _activeBorder.top()){
		return Qt::TopDockWidgetArea;
	}

	if (point.y() > _activeBorder.bottom()){
		return Qt::BottomDockWidgetArea;
	}

	if (point.x() < _activeBorder.left()){
		return Qt::LeftDockWidgetArea;
	}

	if (point.x() > _activeBorder.right()){
		return Qt::RightDockWidgetArea;
	}
	return Qt::NoDockWidgetArea;
}


void VxDockSelector::_mouseReleasedIdle(QPoint point)
{
	QPoint p = parentWidget()->mapFromGlobal(point);

	if (isHidden()){
		if (_inActive(p) == _orientation){
			_showButton(p, true);
		}
	}

}


void VxDockSelector::_mouseReleasedMove(QPoint point)
{
	QPoint p = parentWidget()->mapFromGlobal(point);

	if (isVisible() && _showAnimation->direction() == QAbstractAnimation::Forward){
		if (_inActive(p) != _orientation){
			_hideButton(true);
		}

	}

}


void VxDockSelector::_showDockContainer()
{
	_container->showByOrientation(_orientation);
	QRect wr = parentWidget()->geometry();

	int mx = x() + WIDTH/2 - _container->width()/2;
	int my = y() + WIDTH/2 - _container->height()/2;

	switch(_orientation){

	case Qt::LeftDockWidgetArea:{
			mx = HEIGHT * 2;
			break;
		}

	case Qt::RightDockWidgetArea:{
			mx = wr.width() - HEIGHT * 2 - _container->width();
			break;
		}
	case Qt::TopDockWidgetArea:{
			my = HEIGHT*2;
			break;
		}
	case Qt::BottomDockWidgetArea:{
			my = wr.height() - HEIGHT * 2 - _container->height();
			break;
		}
	default:;
	}

	if (mx < HEIGHT){
		mx = HEIGHT;
	} else
	if (mx + _container->width() > wr.width() - HEIGHT){
		mx = wr.width() - HEIGHT - _container->width();
	}

	if (my < HEIGHT){
		my = HEIGHT;
	} else
	if (my + _container->height() > wr.height() - HEIGHT){
		my = wr.height() - HEIGHT - _container->height();
	}

	_container->move(mx, my);
	_container->show();

}















